home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / lib / linuxmint / mintInstall / mintInstall.py < prev    next >
Encoding:
Python Source  |  2007-05-16  |  13.1 KB  |  410 lines

  1. #!/usr/bin/env python
  2.  
  3. # mintInstall
  4. #    No Copyright (What for?) Clem <root@linuxmint.com>
  5. #
  6. # This program is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU General Public License
  8. # as published by the Free Software Foundation; Version 2
  9. # of the License.
  10. #
  11. # This program is "inspired" by CNR and the idea of "one click install". 
  12.  
  13.  
  14. import sys
  15. import apt
  16. import vte
  17. import fcntl
  18. import apt_pkg
  19. import vte
  20. import posix
  21. import string
  22.  
  23. from apt.progress import OpProgress, FetchProgress, InstallProgress
  24.  
  25. try:
  26.      import pygtk
  27.      pygtk.require("2.0")
  28. except:
  29.       pass
  30. try:
  31.     import gtk
  32.     import gtk.glade
  33.     import pango
  34.     import os
  35.     import gconf
  36.     import locale
  37.     import commands
  38.     import threading
  39.     import time
  40.  
  41. except:
  42.     print "You do not have all the dependencies!"
  43.     sys.exit(1)
  44.  
  45. gtk.gdk.threads_init()
  46.  
  47.  
  48. class GuiFetchProgress(FetchProgress):
  49.     def __init__(self, progressbar):
  50.     self.progress = progressbar
  51.  
  52.     def start(self):
  53.         #print "start"
  54.     #self.progress.set_fraction(0)
  55.     pass
  56.  
  57.     def stop(self):
  58.     #print "stop"
  59.     pass
  60.  
  61.     def pulse(self):
  62.         #FetchProgress.pulse(self)
  63.         self.progress.set_text("Speed: %s/s" % apt_pkg.SizeToStr(self.currentCPS))
  64.     percentage = self.currentBytes/self.totalBytes    
  65.     self.progress.set_fraction(percentage)
  66.     os.system("echo " + str(percentage) + "> /usr/lib/linuxmint/mintInstall/tmp/progress")
  67.     #while gtk.events_pending():
  68.     #    gtk.main_iteration()
  69.         return True
  70.  
  71. class TermInstallProgress(InstallProgress):
  72.     def __init__(self, term, progressbar):
  73.     self.term = term
  74.     self.progressbar = progressbar
  75.                 
  76.     # check for the child
  77.         self.reaper = vte.reaper_get()
  78.         self.reaper.connect("child-exited",self.child_exited)
  79.         self.finished = False
  80.         
  81.         (read, write) = os.pipe()
  82.         self.writefd=write
  83.         self.status = os.fdopen(read, "r")
  84.         fcntl.fcntl(self.status.fileno(), fcntl.F_SETFL,os.O_NONBLOCK)
  85.         #print "read-fd: %s" % self.status.fileno()
  86.         #print "write-fd: %s" % self.writefd
  87.         self.read = ""
  88.     #print "<--init"
  89.  
  90.     def child_exited(self,term, pid, status):
  91.     #print "-->child exited"        
  92.     #print "child_exited: %s %s %s %s" % (self,term,pid,status)
  93.         self.apt_status = posix.WEXITSTATUS(0)
  94.         self.finished = True
  95.     #print "<--child exited"
  96.  
  97.     #def startUpdate(self):
  98.     #    print "-->startupdate"
  99.     #    print "<--startupdate"
  100.  
  101.     def updateInterface(self):
  102.     #print "-->updateInterface"
  103.         if self.status != None:
  104.                 try:
  105.                     self.read += os.read(self.status.fileno(),1)
  106.                 except OSError, (errno,errstr):
  107.                     # resource temporarly unavailable is ignored
  108.                     if errno != 11: 
  109.                         print errstr
  110.                 if self.read.endswith("\n"):
  111.                     s = self.read
  112.                     #print s
  113.                     (status, pkg, percent, status_str) = string.split(s, ":")
  114.                     #print "percent: %s %s" % (pkg, float(percent)/100.0)
  115.                     self.progressbar.set_fraction(float(percent)/100.0)
  116.                     self.progressbar.set_text(string.strip(status_str))
  117.                     self.read = ""
  118.         #while gtk.events_pending():
  119.         #    gtk.main_iteration()
  120.     #print "<--updateInterface"
  121.         
  122.     #def finishUpdate(self):
  123.     #print "-->finishUpdate"
  124.     #sys.stdin.readline()
  125.     #print "<--finishUpdate"
  126.  
  127.     def run(self, pm):
  128.     #print "-->run"        
  129.     #print "fork"
  130.         env = ["VTE_PTY_KEEP_FD=%s"%self.writefd]
  131.         #print env
  132.     pid = self.term.forkpty(envv=env)
  133.         if pid == 0:
  134.             res = pm.DoInstall(self.writefd)
  135.             #print res
  136.             sys.exit(res)
  137.         #print "After fork: %s " % pid
  138.         while not self.finished:
  139.             self.updateInterface()
  140.         return self.apt_status
  141.  
  142. class mintInstallExecuter(threading.Thread):
  143.     
  144.     def execute(self, command):
  145.     #print "Executing: " + command
  146.     os.system(command)
  147.     ret = commands.getoutput("echo $?")
  148.     return ret
  149.  
  150.     def run(self):
  151.     global steps
  152.     global progressbar
  153.     global wTree
  154.     global installation_terminal
  155.     global installation_progressbar
  156.     global download_progressbar
  157.     global packages
  158.  
  159.     wTree.get_widget("main_button").hide()
  160.     wTree.get_widget("cancel_button").hide()
  161.     
  162.     progressbar.set_text("Backing up your APT sources")
  163.     self.execute("mv /etc/apt/sources.list /etc/apt/sources.list.mintbackup")
  164.     self.execute("cp /usr/lib/linuxmint/mintInstall/sources.list /etc/apt/sources.list")
  165.     self.execute("apt-get update")
  166.     fraction = float(1)/float(steps+2)
  167.     progressbar.set_fraction(fraction)
  168.  
  169.     for i in range(steps + 1):
  170.         if (i > 0):            
  171.             openfile = open("/usr/lib/linuxmint/mintInstall/tmp/steps/"+str(i), 'r' )
  172.                         datalist = openfile.readlines()
  173.             for j in range( len( datalist ) ):
  174.                             if (str.find(datalist[j], "TITLE") > -1):
  175.                 title = datalist[j][6:]
  176.                 progressbar.set_text(str.strip(title))
  177.                 if (str.find(datalist[j], "INSTALL") > -1):
  178.                 install = datalist[j][8:]
  179.                 install = str.strip(install)
  180.                 cache = apt.Cache()
  181.                 fprogress = GuiFetchProgress(download_progressbar)
  182.                 iprogress = TermInstallProgress(installation_terminal, installation_progressbar)
  183.                 pkg = cache[install]
  184.                 if not pkg.isInstalled:
  185.                     pkg.markInstall()
  186.                 cache.commit(fprogress, iprogress)
  187.                 if (str.find(datalist[j], "SOURCE") > -1):
  188.                 source = datalist[j][7:]
  189.                 source = source.rstrip()
  190.                 self.execute("echo \"" + source + "\" >> /etc/apt/sources.list")
  191.                 self.execute("apt-get update")
  192.                 
  193.             fraction = float(i+1)/float(steps+2)
  194.             progressbar.set_fraction(fraction)
  195.     
  196.     progressbar.set_text("Restoring your APT sources")        
  197.     self.execute("mv /etc/apt/sources.list.mintbackup /etc/apt/sources.list")
  198.     self.execute("apt-get update")
  199.     progressbar.set_fraction(1)
  200.     
  201.     progressbar.set_text("Finished")
  202.     #wTree.get_widget("main_button").hide()
  203.     #wTree.get_widget("cancel_button").set_label("Close")
  204.     # Check that all packages are now installed
  205.     txt_packages = ""
  206.     allPackagesAreInstalled = True
  207.     for package in packages: 
  208.         number_installed = commands.getoutput("aptitude search " + package + " | grep ^i | wc -l")
  209.         if (number_installed == "0"):
  210.             txt_packages = package + " (not installed)\n"
  211.             allPackagesAreInstalled = False
  212.         else:
  213.             txt_packages = package + " (installed)\n"
  214.     txt_packages = str.strip(txt_packages)
  215.     dialog_gladefile = "/usr/lib/linuxmint/mintInstall/mintInstall.glade"
  216.         dialog_wTree = gtk.glade.XML(dialog_gladefile,"message_dialog")
  217.  
  218.     #Set a new style for the status
  219.         HeadingStyle = pango.AttrList()
  220.         attr = pango.AttrSize(13000,0,-1)
  221.         HeadingStyle.insert(attr)
  222.         attr = pango.AttrForeground(24576,34816,41728,0,-1)
  223.         HeadingStyle.insert(attr)
  224.         dialog_wTree.get_widget("txt_status").set_attributes(HeadingStyle)
  225.  
  226.     if (allPackagesAreInstalled):
  227.         dialog_wTree.get_widget("txt_status").set_text("Success")    
  228.     else:
  229.         dialog_wTree.get_widget("txt_status").set_text("Failure")
  230.     
  231.     dialog_wTree.get_widget("txt_packages_status").set_text(txt_packages)
  232.  
  233.     button = dialog_wTree.get_widget("ok_button")    
  234.     button.connect("clicked",gtk.main_quit)
  235.     dialog = dialog_wTree.get_widget("message_dialog")    
  236.     dialog.set_parent(wTree.get_widget("main_window"))
  237.     dialog.show()
  238.  
  239. class mintInstallWindow:
  240.     """This is the main class for the application"""
  241.  
  242.     def __init__(self, mintFile):
  243.     global steps
  244.     global progressbar
  245.     global wTree
  246.     global installation_terminal
  247.     global installation_progressbar
  248.     global download_progressbar
  249.     global packages
  250.  
  251.     self.mintFile = mintFile    
  252.  
  253.     #Make tmp folder
  254.     os.system("mkdir -p /usr/lib/linuxmint/mintInstall/tmp")
  255.  
  256.     #Clean tmp files
  257.     os.system("rm -rf /usr/lib/linuxmint/mintInstall/tmp/*") 
  258.  
  259.     #Decompress file
  260.     os.system("cp " + mintFile + " /usr/lib/linuxmint/mintInstall/tmp/file.mint")
  261.     os.system("tar zxf /usr/lib/linuxmint/mintInstall/tmp/file.mint -C /usr/lib/linuxmint/mintInstall/tmp/")
  262.  
  263.     #Extract the name
  264.     self.name = commands.getoutput("cat /usr/lib/linuxmint/mintInstall/tmp/name")    
  265.     self.name = str.strip(self.name)
  266.  
  267.     #Extract the description
  268.     self.description = commands.getoutput("cat /usr/lib/linuxmint/mintInstall/tmp/description")
  269.     self.description = str.strip(self.description)
  270.  
  271.         #Extract the version
  272.     self.version = commands.getoutput("cat /usr/lib/linuxmint/mintInstall/tmp/version")
  273.     self.version = str.strip(self.version)
  274.  
  275.     #Extract the number of steps
  276.     steps = int(commands.getoutput("ls -l /usr/lib/linuxmint/mintInstall/tmp/steps/ | wc -l"))
  277.     steps = steps -1
  278.     self.pulse = 1/steps
  279.  
  280.     #Extract repositories and packages
  281.     self.repositories = []
  282.     packages = []
  283.     for i in range(steps + 1):
  284.         if (i > 0):            
  285.             openfile = open("/usr/lib/linuxmint/mintInstall/tmp/steps/"+str(i), 'r' )
  286.                         datalist = openfile.readlines()
  287.             for j in range( len( datalist ) ):
  288.                 if (str.find(datalist[j], "INSTALL") > -1):
  289.                 install = datalist[j][8:]
  290.                 install = str.strip(install)
  291.                 packages.append(install)
  292.                 if (str.find(datalist[j], "SOURCE") > -1):
  293.                 source = datalist[j][7:]
  294.                 source = source.rstrip()
  295.                 self.repositories.append(source)    
  296.             #openfile.close()
  297.     
  298.         #Set the Glade file
  299.         self.gladefile = "/usr/lib/linuxmint/mintInstall/mintInstall.glade"
  300.         wTree = gtk.glade.XML(self.gladefile,"main_window")
  301.  
  302.         #Set a new style for the name
  303.         HeadingStyle = pango.AttrList()
  304.         attr = pango.AttrSize(13000,0,-1)
  305.         HeadingStyle.insert(attr)
  306.         attr = pango.AttrForeground(24576,34816,41728,0,-1)
  307.         HeadingStyle.insert(attr)
  308.         wTree.get_widget("txt_name").set_attributes(HeadingStyle)
  309.  
  310.         #Create our dictionay and connect it
  311.         dic = {"on_main_button_clicked" : (self.MainButtonClicked),
  312.                "on_cancel_button_clicked" : (gtk.main_quit) }
  313.         wTree.signal_autoconnect(dic)
  314.  
  315.     #Fill in the GUI with information from the mintFile
  316.     wTree.get_widget("txt_name").set_text(self.name + " " + self.version)    
  317.     wTree.get_widget("txt_description").set_text(self.description)
  318.     txt_packages = ""
  319.     packages.sort()
  320.     self.needToInstallSomething = False
  321.     for package in packages: 
  322.         number_installed = commands.getoutput("aptitude search " + package + " | grep ^i | wc -l")
  323.         if (number_installed == "0"):
  324.             txt_packages = package + " (not installed)\n"
  325.             self.needToInstallSomething = True
  326.         else:
  327.             txt_packages = package + " (installed)\n"
  328.     txt_packages = str.strip(txt_packages)
  329.     wTree.get_widget("txt_packages").set_text(txt_packages)
  330.     txt_repositories = ""
  331.     self.repositories.sort()
  332.     for repository in self.repositories: 
  333.         txt_repositories = repository + "\n"
  334.     txt_repositories = str.strip(txt_repositories)
  335.     wTree.get_widget("main_button").set_sensitive(self.needToInstallSomething)
  336.     wTree.get_widget("image_icon").set_from_file("/usr/lib/linuxmint/mintInstall/tmp/icon")        
  337.     wTree.get_widget("txt_repositories").set_text(txt_repositories)
  338.     progressbar = wTree.get_widget("progressbar1")
  339.     fraction = 0
  340.     progressbar.set_fraction(fraction)
  341.  
  342.     download_progressbar = wTree.get_widget("download_progressbar")
  343.  
  344.     # Set the installation box
  345.     box = wTree.get_widget("installation_box")
  346.         installation_terminal = vte.Terminal()
  347.     installation_terminal.set_background_transparent(True)    
  348.     installation_terminal.show()
  349.         box.pack_start(installation_terminal)
  350.         installation_progressbar = gtk.ProgressBar()
  351.         installation_progressbar.show()
  352.         box.pack_start(installation_progressbar)
  353.  
  354.     def MainButtonClicked(self, widget):
  355.     executer = mintInstallExecuter()
  356.     executer.start()
  357.     return True
  358.  
  359. class InstanceDialog:
  360.     def __init__(self):
  361.  
  362.         #Set the Glade file
  363.         self.gladefile = "/usr/lib/linuxmint/mintInstall/mintInstall.glade"
  364.  
  365.     def run(self,message):
  366.         """This function will show the Instance Dialog"""
  367.         self.wTree = gtk.glade.XML(self.gladefile, "dialog3")
  368.         #Get the actual dialog widget
  369.         self.dlg = self.wTree.get_widget("dialog3")
  370.         self.wTree.get_widget("label164").set_label((message))
  371.         #run the dialog and store the response
  372.         self.result = self.dlg.run()
  373.         #we are done with the dialog, destroy it
  374.         self.dlg.destroy()
  375.         #return the result
  376.         return self.result
  377.  
  378.  
  379. if __name__ == "__main__":
  380.     if (os.path.exists("/etc/apt/sources.list.mintbackup")):
  381.     os.system("mv /etc/apt/sources.list.mintbackup /etc/apt/sources.list")
  382.     os.system("apt-get update")
  383.         warnDlg = gtk.Dialog(title="MintInstall", parent=None, flags=0, buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK))
  384.     warnDlg.vbox.set_spacing(10)
  385.     labelSpc = gtk.Label(" ")
  386.     warnDlg.vbox.pack_start(labelSpc)    
  387.     labelSpc.show()
  388.     warnText = ("<b>Your APT sources were corrupted.</b>")
  389.     infoText = ("Your APT sources were not correctly restored after you last ran mintInstall. They now have been restored.")
  390.     label = gtk.Label(warnText)
  391.     lblInfo = gtk.Label(infoText)
  392.     label.set_use_markup(True)
  393.     lblInfo.set_use_markup(True)
  394.     warnDlg.vbox.pack_start(label)
  395.     warnDlg.vbox.pack_start(lblInfo)
  396.     label.show()
  397.     lblInfo.show()
  398.     response = warnDlg.run()
  399.     if response == gtk.RESPONSE_OK :
  400.         warnDlg.destroy()
  401.         #gtk.main_quit()
  402.         sys.exit(0)
  403.     else:
  404.     os.system("rm -rf /var/lib/dpkg/lock")
  405.     os.system("rm -rf /var/lib/apt/lists/lock") 
  406.     os.system("rm -rf /var/cache/apt/archives/lock")
  407.         mainwin = mintInstallWindow(sys.argv[1])
  408.         gtk.main()
  409.     
  410.